/* *****************************************************************
 *
 * Download latest Blinker library here:
 * https://github.com/blinker-iot/blinker-library/archive/master.zip
 * 
 * 
 * Blinker is a cross-hardware, cross-platform solution for the IoT. 
 * It provides APP, device and server support, 
 * and uses public cloud services for data transmission and storage.
 * It can be used in smart home, data monitoring and other fields 
 * to help users build Internet of Things projects better and faster.
 * 
 * Make sure installed 2.5.0 or later ESP8266/Arduino package,
 * if use ESP8266 with Blinker.
 * https://github.com/esp8266/Arduino/releases
 * 
 * Make sure installed 1.0.2 or later ESP32/Arduino package,
 * if use ESP32 with Blinker.
 * https://github.com/espressif/arduino-esp32/releases
 * 
 * Docs: https://doc.blinker.app/
 *       https://github.com/blinker-iot/blinker-doc/wiki
 * 
 * *****************************************************************
 * 
 * Blinker 库下载地址:
 * https://github.com/blinker-iot/blinker-library/archive/master.zip
 * 
 * Blinker 是一套跨硬件、跨平台的物联网解决方案，提供APP端、设备端、
 * 服务器端支持，使用公有云服务进行数据传输存储。可用于智能家居、
 * 数据监测等领域，可以帮助用户更好更快地搭建物联网项目。
 * 
 * 如果使用 ESP8266 接入 Blinker,
 * 请确保安装了 2.5.0 或更新的 ESP8266/Arduino 支持包。
 * https://github.com/esp8266/Arduino/releases
 * 
 * 如果使用 ESP32 接入 Blinker,
 * 请确保安装了 1.0.2 或更新的 ESP32/Arduino 支持包。
 * https://github.com/espressif/arduino-esp32/releases
 * 
 * 文档: https://doc.blinker.app/
 *       https://github.com/blinker-iot/blinker-doc/wiki
 * 
 * *****************************************************************/

#define BLINKER_WIFI
#define BLINKER_MIOT_MULTI_OUTLET
#include <Blinker.h>

char auth[] = "913344eefd49";
char ssid[] = "robot_test";
char pswd[] = "robot123";

#define BUTTON_1 "btn-1"
#define BUTTON_2 "btn-2"
#define BUTTON_3 "btn-3"
#define BUTTON_4 "btn-4"
#define BUTTON_5 "btn-5"
#define BUTTON_6 "btn-6"

BlinkerButton Button1(BUTTON_1);
BlinkerButton Button2(BUTTON_2);
BlinkerButton Button3(BUTTON_3);
BlinkerButton Button4(BUTTON_4);
BlinkerButton Button5(BUTTON_5);
BlinkerButton Button6(BUTTON_6);

#define GPIO433 16

void t()
{
  delayMicroseconds(270);
}
  
void high_level()
{
  digitalWrite(GPIO433, HIGH);
  t();t();t();
  digitalWrite(GPIO433, LOW);
  t();
}

void low_level()
{
  digitalWrite(GPIO433, HIGH);
  t();
  digitalWrite(GPIO433, LOW);
  t();t();t();
}

void high_code()
{
  high_level();
  high_level();
}

void low_code()
{
  low_level();
  low_level();
}

void nop_code()
{
  low_level();
  high_level();
}

void syn()
{
  digitalWrite(GPIO433, LOW);
  t();
  t();t();t();t();t();t();t();t();t();t();
  t();t();t();t();t();t();t();t();t();t();
  t();t();t();t();t();t();t();t();
}

void left_action(const int code)
{
  high_code();
  low_code();
  nop_code();
  high_code();
  nop_code();
  high_code();
  nop_code();
  high_code();
  switch(code) {
    case 1:
      high_code();
      low_code();
      low_code();
      low_code();
      break;
    case 2:
      low_code();
      high_code();
      low_code();
      low_code();
      break;
    case 3:
      low_code();
      low_code();
      high_code();
      low_code();
      break;
    case 4:
      low_code();
      low_code();
      low_code();
      high_code();
      break;  
  }
  syn();
}

void right_action(const int code)
{
  high_code();
  low_code();
  nop_code();
  high_code();
  nop_code();
  high_code();
  nop_code();
  high_code();
  switch(code) {
    case 1:
      high_code();
      low_code();
      low_code();
      low_code();
      break;
    case 2:
      low_code();
      high_code();
      low_code();
      low_code();
      break;
    case 3:
      low_code();
      low_code();
      high_code();
      low_code();
      break;
    case 4:
      low_code();
      low_code();
      low_code();
      high_code();
      break;  
  }
  syn();
}
//打开左车库门
void button1_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-1: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        left_action(1);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}
//关闭左车库门
void button2_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-2: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        left_action(2);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}
//打开右车库门
void button3_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-3: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        right_action(1);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}
//关闭右车库门
void button4_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-4: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        right_action(2);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}
//暂停左车库门
void button5_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-5: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        left_action(4);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}
//暂停右车库门
void button6_callback(const String & state)
{
  BLINKER_LOG("Blinker btn-6: ", state);
  if (state == BLINKER_CMD_BUTTON_TAP) {
      for(int i=0; i<5; i++) {
        right_action(4);
      }
  }
  Blinker.vibrate();
  uint32_t BlinkerTime = millis();
  Blinker.print("millis", BlinkerTime);
}

void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);

    Blinker.vibrate();
    
    uint32_t BlinkerTime = millis();
    
    Blinker.print("millis", BlinkerTime);
}

void setup()
{
    Serial.begin(115200);
    BLINKER_DEBUG.stream(Serial);

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    pinMode(GPIO433, OUTPUT);
    digitalWrite(GPIO433, LOW);

    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);
    
    Button1.attach(button1_callback);
    Button2.attach(button2_callback);
    Button3.attach(button3_callback);
    Button4.attach(button4_callback);
    Button5.attach(button5_callback);
    Button6.attach(button6_callback);
}

void loop()
{
    Blinker.run();
}
